#include "iso_movable.h"

#include "tools.h"

namespace
{
    constexpr int kDefaultStaticFrame{1};
}

movableSprite::movableSprite(const int posX, const int posY, const bn::sprite_item& movableItem, const int collisionWidth, const int collisionHeight, const int moveSpeed, const int spriteHeight)
    : staticSprite{posX, posY, movableItem, collisionWidth, collisionHeight, spriteHeight}
    , canMove{false}
    , speed{moveSpeed}
    , dir{Direction::Down}
    , animationTilesItem{movableItem.tiles_item()}
{
    animationFrames.insert({Direction::Up,bn::array<int, 4>{10,9,11,9}});
    animationFrames.insert({Direction::Down,bn::array<int, 4>{1,0,2,0}});
    animationFrames.insert({Direction::Left,bn::array<int, 4>{7,6,8,6}});
    animationFrames.insert({Direction::Right,bn::array<int, 4>{4,3,5,3}});
}

void movableSprite::setDirection(const Direction& newDir)
{
    dir = newDir;
}

void movableSprite::setAsMovable(const bool canMove_)
{
    canMove = canMove_;
}

void movableSprite::setMoveAnimation()
{
    moveAnimation = bn::create_sprite_animate_action_forever(spritePtr, speed, animationTilesItem.value(),
                                                             animationFrames[dir][0], animationFrames[dir][1], animationFrames[dir][2], animationFrames[dir][3]);
}

void movableSprite::setStaticFrame()
{
    spritePtr.set_tiles(animationTilesItem.value(), animationFrames[dir][kDefaultStaticFrame]);
}

void movableSprite::draw()
{
    spritePtr.set_position(tool::convert2dToScreenPoint(currentPosX, currentPosY, collisionRect.width().integer(), collisionRect.height().integer()));
}

void movableSprite::update()
{
    if(moveAnimation.has_value())
    {
        moveAnimation->update();
    }

    if (!canMove)
    {
        return;
    }

    switch (dir)
    {
    case Direction::Up:
        --currentPosY;
        collisionRect.set_y(currentPosY+spriteHeight/2);
        break;
    case Direction::Down:
        ++currentPosY;
        collisionRect.set_y(currentPosY+spriteHeight/2);
        break;
    case Direction::Left:
        --currentPosX;
        collisionRect.set_x(currentPosX);
        break;
    case Direction::Right:
        ++currentPosX;
        collisionRect.set_x(currentPosX);
        break;
    default:
        break;
    }
}
